/**
* @file app_common.c
* @brief Common process - adapter the flash api
* @version 0.1
* @date 2021-10-22
*
* @copyright Copyright 2020-2021 Tuya Inc. All Rights Reserved.
*
*/
#include "tkl_pwm.h"
#include "tkl_network_manager.h"

#include "tal_system.h"
#include "tal_memory.h"
#include "tal_log.h"
#include "tal_pwm.h"
#include "tal_gpio.h"
#include "tal_uart.h"
#include "tal_flash.h"
#include "tal_sw_timer.h"
#include "tal_attribute_rw.h"
#include "app_light_control.h"
#include "app_common.h"
#include "tal_nv_flash.h"


#define PWM_MIN_FREQ            100   ///< PWM MIN Frequency 100
#define PWM_MAX_FREQ            20000 ///< PWM MAX Frequency 20K
#define PWM_MAX_DUTY            1000  ///< PWM MAX Duty 1000 --> Precision 0.1%

#define pwm_ch_num              2
#define pwm_duty                500
#define pwm_frequency           1000
#define pwm_polarity            TUYA_PWM_POSITIVE

#define KEY_SCAN_MAX_CNT        250
#define PIN_NUM_ERROR           0xFF
#define TUYA_FLASH_PAGE_SIZE    (8 * 1024UL)


extern TIMER_ID etimer_shande;
extern TIMER_ID etimer_key_scan;
extern TIMER_ID etimer_blink_sw;
extern TIMER_ID etimer_countdown;
extern TIMER_ID etimer_join_start_delay;
extern TIMER_ID etimer_power_on_sync;

STATIC UINT16_T sg_key_scan_cnt = 0;
// UINT8_T g_power_on_sync = 0;
UINT8_T g_power_on_state = 0;
UINT16_T g_power_on_bright = 0;
UINT16_T g_power_on_temperature = 0;

TUYA_PWM_POLARITY_E g_pwm_bPolarity = TUYA_PWM_NEGATIVE;
BOOL_T g_user_pwm_init_flag = FALSE;

extern OPERATE_RET tkl_pwm_mapping_to_gpio(UINT32_T ch_id, UINT32_T gpio_id);
// extern OPERATE_RET tkl_pwm_idle_level_set(UINT32_T ch_id, UINT8_T idle_level);
/**
 * @note __dev_power_on_reset_data
 * @param [in] none 
 * @param [out] none
 * @note user can recover light date or set default data in this function
 * @return: none
 */
STATIC VOID_T __dev_power_on_reset_data(VOID_T)
{
    ZG_NWK_TYPE_E nwk_type = tkl_zg_nwk_type_get();

    APP_DATA_T v_app_dcb;
    TAL_KV_STATUS_T v_ret =TAL_KV_SUCC;

    v_ret =TAL_KV_SUCC;
    v_ret=tal_kv_flash_read(KV_ID_APP_DATA, sizeof(APP_DATA_T),  (UCHAR_T *)&v_app_dcb);
    if (v_ret !=TAL_KV_SUCC){
        TAL_PR_DEBUG("power on load app data error:%d",v_ret);
    }

    app_light_ctrl_data_switch_set(v_app_dcb.onoff);
    app_light_ctrl_data_mode_set(WHITE_MODE);            ///< tuya private light mode set
    app_light_ctrl_data_bright_set(v_app_dcb.bright, 0); ///< tuya private bright set
    TAL_PR_DEBUG("nwk_type =%d", nwk_type);

    app_light_ctrl_data_temp_set(v_app_dcb.temperature, 0);

    ULONG_T delay_ms = 0;
    delay_ms = 15000 + tal_system_get_random(5000);
    tal_sw_timer_start(etimer_power_on_sync, delay_ms, TAL_TIMER_ONCE);
}
/**
 * @brief 
 * 
 * @param str 
 * @return VOID_T 
 */
VOID_T dev_uart_output(IN CONST CHAR_T *str)
{
    tal_uart_write((TUYA_UART_NUM_E)USER_UART0, (CONST UINT8_T *)str, strlen(str));
}
/**
 * @brief 
 * 
 * @param args 
 * @return VOID_T 
 */
STATIC VOID_T __dev_pin_irq_handle(VOID_T *args)
{
    sg_key_scan_cnt = 0;
    tal_sw_timer_start(etimer_key_scan, 20, TAL_TIMER_ONCE);
}
/**
 * @brief 
 * 
 * @return OPERATE_RET 
 */
OPERATE_RET app_pwm_init(VOID_T)
{
    OPERATE_RET v_ret = OPRT_COM_ERROR;

    tkl_pwm_mapping_to_gpio((UINT32_T)TUYA_PWM_NUM_0, USER_PWM_CH0_PIN); //PC2
    tkl_pwm_mapping_to_gpio((UINT32_T)TUYA_PWM_NUM_1, USER_PWM_CH1_PIN); //PC3
    
    TUYA_PWM_BASE_CFG_T v_cfg = {
        .duty = 0,
        .frequency = pwm_frequency,
        .polarity = pwm_polarity,
    };

    tkl_pwm_idle_level_set(TUYA_PWM_NUM_0, 0);
    tkl_pwm_idle_level_set(TUYA_PWM_NUM_1, 0);
    
    v_ret = tal_pwm_init(TUYA_PWM_NUM_0, &v_cfg);
    v_ret = tal_pwm_init(TUYA_PWM_NUM_1, &v_cfg);

    tal_pwm_start(0xFF);

    g_user_pwm_init_flag = TRUE;
    g_pwm_bPolarity = pwm_polarity;
    app_light_ctrl_ch_num_set(pwm_ch_num);
    TAL_PR_DEBUG("pwm init ok!");
    return v_ret;
}
/**
 * @note light init 
 *          1. pwm init;
 *          2. reset cnt processing
 *          3. power on config default light dada
 *          4. turn on light
 * @param [in] none 
 * @return: OPERATE_RET
 */
OPERATE_RET app_light_init(VOID_T)
{
    app_pwm_init();
    __dev_power_on_reset_data();
    app_light_ctrl_proc();
    return OPRT_OK;
}
/**
 * @brief 
 * 
 * @return VOID_T 
 */
VOID_T app_button_init(VOID_T)
{
    TUYA_GPIO_IRQ_T irq_cfg = {
        .mode = TUYA_GPIO_IRQ_FALL,
        .cb = __dev_pin_irq_handle,
        .arg = NULL,
    };
    tal_gpio_irq_init(USER_KEY0, &irq_cfg);//PC0
}
/**
 * @brief 
 * 
 * @param timer_id 
 * @param arg 
 * @return VOID_T 
 */
VOID_T app_button_scan_cb(TIMER_ID timer_id, VOID_T *arg)
{
    TUYA_GPIO_LEVEL_E v_level = TUYA_GPIO_LEVEL_HIGH;

    if (OPRT_OK != tal_gpio_read(USER_KEY0, &v_level))
    {
        return;
    }

    if (v_level == TUYA_GPIO_LEVEL_HIGH)
    {
        sg_key_scan_cnt = 0;
    }
    else
    {
        sg_key_scan_cnt++;
        if (sg_key_scan_cnt >= KEY_SCAN_MAX_CNT)
        {
            tal_sw_timer_start(etimer_join_start_delay, 50, TAL_TIMER_ONCE);
            return;
        }
        tal_sw_timer_start(etimer_key_scan, 20, TAL_TIMER_ONCE);
    }
}
/**
 * @brief Get the option value object
 * 
 * @param cluster 
 * @param optionMask 
 * @param optionOverride 
 * @return UCHAR_T 
 */
UCHAR_T app_zcl_get_option_value(ZG_CLUSTER_ID_E cluster, UCHAR_T optionMask, UCHAR_T optionOverride)
{
    UCHAR_T option = 0;
    UCHAR_T state = 0;

    state = tal_zg_read_attribute(1, cluster, OPTION_ATTRIBUTE_ID, &option, sizeof(option));
    if (state != OPRT_OK)
    {
        option = 0;
    }

    if (optionMask == 0x01)
    {
        if (optionOverride == 0x01)
        {
            option = 0x01;
        }
        else
        {
            option = 0x00;
        }
    }
    if (option != 0)
    {
        option = 1;
    }
    return option;
}
